﻿package com.dao;

import java.sql.SQLException;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

@SuppressWarnings("unchecked")
public class BaseDAO<T> extends HibernateDaoSupport {
	
	private Class<T> entityClass;
	private static final Logger logger = Logger.getLogger(BaseDAO.class);
	
	@Autowired
	public void setMySessionFactory(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);
	}
	
	public BaseDAO(Class<T> entityClass) {
		this.entityClass = entityClass;
	}
	
	public boolean delete(int id) {
		logger.debug("正在删除记录...");
		try{
			getHibernateTemplate().delete(find(id));
			logger.debug("删除成功！");
			return true;
		}catch(RuntimeException e){
			logger.error("删除记录出错！原因：" + e.getMessage());
			return false;
		}
	}

	public T find(int id) {
		logger.debug("根据主键查找记录...");
		try {
			return getHibernateTemplate().get(entityClass, id);
		} catch (RuntimeException e) {
			logger.error("根据主键查找记录出错！原因：" + e.getMessage());
			throw e;
		}
	}

	public List<T> findAll(String orderBy) {
		logger.debug("查找所有记录...");
		try{
			String queryString = "from " + entityClass.getSimpleName() + " order by " + orderBy;
			return getHibernateTemplate().find(queryString);
		}catch(RuntimeException e){
			logger.error("查找所有记录失败！原因：" + e.getMessage());
			throw e;
		}
	}
	
	public List<T> findAll() {
		logger.debug("查找所有记录...");
		try{
			String queryString = "from " + entityClass.getSimpleName();
			return getHibernateTemplate().find(queryString);
		}catch(RuntimeException e){
			logger.error("查找所有记录失败！原因：" + e.getMessage());
			throw e;
		}
	}

	public List<T> findAllInPage(final int start, final int limit) {
		logger.debug("分页查找所有记录...");
		try{
			final String queryString = "from " + entityClass.getSimpleName();
			return getHibernateTemplate().executeFind(new HibernateCallback(){

				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					List<T> result = session.createQuery(queryString)
								.setFirstResult(start)	//设置页面第一条记录
								.setMaxResults(limit)	//设置页面最大记录数
								.list();
					return result;
				}
				
			});
		}catch(RuntimeException e){
			logger.error("分页查找所有记录失败！原因：" + e.getMessage());
			throw e;
		}
	}
	
	public List<T> findAllInPage(final int start, final int limit, String orderBy) {
		logger.debug("分页查找所有记录...");
		try{
			final String queryString = "from " + entityClass.getSimpleName() + " order by " + orderBy;
			return getHibernateTemplate().executeFind(new HibernateCallback(){

				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					List<T> result = session.createQuery(queryString)
								.setFirstResult(start)	//设置页面第一条记录
								.setMaxResults(limit)	//设置页面最大记录数
								.list();
					return result;
				}
				
			});
		}catch(RuntimeException e){
			logger.error("分页查找所有记录失败！原因：" + e.getMessage());
			throw e;
		}
	}

	public Long findAllCount() {
		logger.debug("查找所有记录总数...");
		try{
			final String queryString = "select count(*) from " + entityClass.getSimpleName();
			List list = getHibernateTemplate().find(queryString);
			if(list != null && list.size() > 0){
				return (Long) list.get(0);
			}
			return new Long(0);
		}catch(RuntimeException e){
			logger.error("查找所有记录总数失败！原因：" + e.getMessage());
			throw e;
		}
	}

	protected List<T> findByProperty(String propertyName, Object propertyValue, String orderBy) {
		logger.debug("根据实体属性查找记录...");
		try{
			final String queryString;
			if(orderBy == null || "".equals(orderBy)){
				 queryString = "from " + entityClass.getSimpleName() + " o where o." + propertyName + "=?";
			}else{
				queryString = "from " + entityClass.getSimpleName() + " o where o." + propertyName + "=? order by " + orderBy;
			}
			return getHibernateTemplate().find(queryString, propertyValue);
		}catch(RuntimeException e){
			logger.error("根据实体属性查找记录失败！原因：" + e.getMessage());
			throw e;
		}
	}
	
	protected List<T> findByPropertyInPage(String propertyName, Object propertyValue, String orderBy, final int start, final int limit) {
		logger.debug("根据实体属性查找记录...");
		try{
			final String queryString;
			if(orderBy == null || "".equals(orderBy)){
				 queryString = "from " + entityClass.getSimpleName() + " o where o." + propertyName + "=?";
			}else{
				queryString = "from " + entityClass.getSimpleName() + " o where o." + propertyName + "=? order by " + orderBy;
			}
			return getHibernateTemplate().executeFind(new HibernateCallback(){

				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					List<T> result = session.createQuery(queryString)
								.setFirstResult(start)	//设置页面第一条记录
								.setMaxResults(limit)	//设置页面最大记录数
								.list();
					return result;
				}
				
			});
		}catch(RuntimeException e){
			logger.error("根据实体属性查找记录失败！原因：" + e.getMessage());
			throw e;
		}
	}

	protected Object findResultCount(String hql, Object... args) {
		logger.debug("根据查询语句查询结果总数...");
		try{
			final String queryString = "select count(*) from " + entityClass.getSimpleName() + " o " + hql;
			List list = getHibernateTemplate().find(queryString, args);
			if(list != null && list.size() > 0){
				return list.get(0);
			}
			return null;
		}catch(RuntimeException e){
			logger.error("根据查询语句查询结果总数失败！原因：" + e.getMessage());
			throw e;
		}
	}

	protected List<T> findResultList(String hql, Object... args) {
		logger.debug("根据查询语句查找...");
		try{
			final String queryString = "from " + entityClass.getSimpleName() + " o " + hql;
			return getHibernateTemplate().find(queryString, args);
		}catch(RuntimeException e){
			logger.error("根据查询语句查找失败！原因：" + e.getMessage());
			throw e;
		}
	}

	protected List<T> findResultListInPage(String hql, final int start, final int limit,
			final Object... args) {
		logger.debug("根据查询语句分页查找...");
		try{
			final String queryString = "from " + entityClass.getSimpleName() + " o " + hql;
			return getHibernateTemplate().executeFind(new HibernateCallback(){

				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					Query query = session.createQuery(queryString);
					for(int i = 0; i < args.length; i++){
						query.setParameter(i, args[i]);
					}
					List<T> result = query
								.setFirstResult(start)	//设置页面第一条记录
								.setMaxResults(limit)	//设置页面最大记录数
								.list();
					return result;
				}
				
			});
		}catch(RuntimeException e){
			logger.error("根据查询语句分页查找失败！原因：" + e.getMessage());
			throw e;
		}
	}

	public boolean insert(T obj) {
		logger.debug("正在插入记录...");
		try{
			getHibernateTemplate().save(obj);
			logger.debug("插入成功！");
			return true;
		}catch(RuntimeException e){
			logger.error("插入记录出错！原因：" + e.getMessage());
			return false;
		}
	}

	public boolean update(T obj) {
		logger.debug("正在更新记录...");
		try{
			getHibernateTemplate().merge(obj);
			logger.debug("更新成功！");
			return true;
		}catch(RuntimeException e){
			logger.error("更新记录出错！原因：" + e.getMessage());
			return false;
		}
	}

	protected Object findResultNum(String hql, Object... args) {
		logger.debug("查找统计操作...");
		try{
			final String queryString = hql.replace("entity", entityClass.getSimpleName());
			List list = getHibernateTemplate().find(queryString, args);
			if(list != null && list.size() > 0){
				return list.get(0);
			}
			return null;
		}catch(RuntimeException e){
			logger.error("查找统计操作失败！原因：" + e.getMessage());
			throw e;
		}
	}

	protected List<T> findResultListInPageByHql(final String hql, final int start, final int limit, final Object... args) {
		logger.debug("根据查询语句分页查找...");
		try{
			return getHibernateTemplate().executeFind(new HibernateCallback(){

				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					Query query = session.createQuery(hql);
					for(int i = 0; i < args.length; i++){
						query.setParameter(i, args[i]);
					}
					List<T> result = query
								.setFirstResult(start)	//设置页面第一条记录
								.setMaxResults(limit)	//设置页面最大记录数
								.list();
					return result;
				}
				
			});
		}catch(RuntimeException e){
			logger.error("根据查询语句分页查找失败！原因：" + e.getMessage());
			throw e;
		}
	}

	protected Object findResultNumByHql(String hql, Object... args) {
		logger.debug("查找统计操作...");
		try{
			List list = getHibernateTemplate().find(hql, args);
			if(list != null && list.size() > 0){
				return list.get(0);
			}
			return null;
		}catch(RuntimeException e){
			logger.error("查找统计操作失败！原因：" + e.getMessage());
			throw e;
		}
	}
}
